﻿/****************************** Module Header ******************************\
 * Module Name:  FormSearchBar.cs
 * Module Version:  1.0.0 (2012-9-28)
 * Copyright (c) AnyEB.Com (14507247@qq.com)
 * 
 * This class is used to process the FormSearchBar.
 * 
 * This source is subject to the GPL License.
 * See http://www.gnu.org/licenses/gpl.html.
 * All other rights reserved.
 * 
 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
using System;
using System.Text;
using System.Linq;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace UCF.Core.Forms.CustomControls.Search
{
    /// <summary>
    /// 搜索控件
    /// </summary>
    public partial class SoSearchBar : UserControl
    {
        /// <summary>
        /// 获取或设置搜索方法
        /// </summary>
        public Action<string> SearchHandler { get; set; }

        public Action<string> PreviewHandler { get; set; }

        /// <summary>
        /// 是否显示搜索模式选项
        /// </summary>
        public bool ShowSearchMode { get { return chkLike.Visible; } set { chkLike.Visible = value; } }

        /// <summary>
        /// 是否使用模糊搜索模式
        /// </summary>
        public bool IsFuzzyMode { get { return chkLike.Checked; } set { chkLike.Checked = value; } }

        /// <summary>
        /// 关键词控件宽度
        /// </summary>
        public int KeyWordWidth { get { return panelWord.Width; } set { panelWord.Width = value; } }

        /// <summary>
        /// 字段控件宽度
        /// </summary>
        public int KeyFieldWidth { get { return cbbKeyField.Width; } set { cbbKeyField.Width = value; } }

        private DataTable _searchField;
        /// <summary>
        /// 获取或设置搜索字段
        /// <para>ID | Name | Type | Default | DataSource</para>
        /// </summary>
        public DataTable SearchField { get { return _searchField; } set { _searchField = value; cbbKeyField.SetDataSource(value); } }

        /// <summary>
        /// 获取或设置关键词
        /// </summary>
        public string KeyWord { get { return tbKeyword.Text.Trim(); } set { tbKeyword.Text = value; } }

        /// <summary>
        /// 是否启用调试模式
        /// </summary>
        public bool IsDebug { get; set; }

        /// <summary>
        /// 是否复合组合查询模式
        /// </summary>
        public bool IsCompositeGroup { get; set; }

        DateTimePicker dtp = new DateTimePicker() { Visible = false };
        ComboBox cbb = new ComboBox() { Visible = false };
        CheckBox chk = new CheckBox() { Visible = false };
        SoSearchAdvanced frmAdv;

        public SoSearchBar()
        {
            InitializeComponent();

            dtp.Format = DateTimePickerFormat.Custom;
            dtp.CustomFormat = "yyyy-MM-dd";
            dtp.TextChanged += new EventHandler(dtp_TextChanged);
            cbb.SelectedIndexChanged += new EventHandler(cbb_SelectedIndexChanged);
            chk.Click += new EventHandler(chk_Click);
            panelWord.Controls.AddRange(new Control[] { dtp, cbb, chk });
            cbb.SetLineHeight();
            cbbKeyField.SetLineHeight();
            frmAdv = new SoSearchAdvanced();
        }
        #region 自定义数据控件事件

        private void dtp_TextChanged(object s, EventArgs e)
        {
            tbKeyword.Text = dtp.Text;
            HideAllControls();
        }
        private void cbb_SelectedIndexChanged(object s, EventArgs e)
        {
            tbKeyword.Text = cbb.GetSelectedValue();
        }
        private void chk_Click(object s, EventArgs e)
        {
            tbKeyword.Text = chk.Checked ? "1" : "0";
        }
        #endregion

        // 打开高级搜索
        private void lnkAdvanced_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            if (frmAdv.IsDisposed) frmAdv = new SoSearchAdvanced();
            frmAdv.Fields = SearchField;
            frmAdv.SearchHandler = SearchHandler;
            frmAdv.IsDebug = IsDebug;
            frmAdv.IsCompositeGroup = IsCompositeGroup;
            frmAdv.PreviewHandler = PreviewHandler;
            frmAdv.Show();
        }

        public void SetSummaryText(string s, params object[] args)
        {
            frmAdv.SummaryText = string.Format(s, args);
        }

        /// <summary>
        /// 添加搜索字段
        /// <para>字段包含:ID | Name | Type | Default | DataSource</para>
        /// <para>Type支持：text,date,bool,group,其中,group格式:value=name&value=name</para>
        /// <para>如：</para>
        /// <para>AddSearchField("ID","编号");</para>
        /// <para>AddSearchField("State","状态","group","0","0=禁用&1=正常");</para>
        /// <para>AddSearchField("Birthday","生日","date","1960-1-1");</para>
        /// </summary>
        /// <param name="id"></param>
        /// <param name="name"></param>
        /// <param name="type">值为：text,date,bool,group,其中,group格式:value=name&value=name</param>
        /// <param name="defv"></param>
        /// <param name="datasource"></param>
        /// <remarks>2014-2-17 by sutroon</remarks>
        private void AddSearchField(string id, string name, string type = "string", string defv = "", string datasource = "")
        {
            DataTable dt = _searchField;
            if (dt == null)
            {
                dt = new DataTable();
                dt.Columns.Add("ID");
                dt.Columns.Add("Name");
                dt.Columns.Add("Type");
                dt.Columns.Add("Default");
                dt.Columns.Add("DataSource");
            }
            dt.Rows.Add(id, name, type, defv, datasource);
            SearchField = dt;
        }

        public void AddSearchField(string id, string name, SearchFieldType type = SearchFieldType.String, string defv = "", string datasource = "")
        {
            AddSearchField(id, name, type.ToString().ToLower(), defv, datasource);
        }

        // 开始搜索(前缀/表示启动自定义模糊匹配)
        private void btnSearch_Click(object sender, EventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            string kw = tbKeyword.Text.Trim(), field = cbbKeyField.GetSelectedValue(), type;
            bool isAccurately = kw.StartsWith("=");
            if (isAccurately) kw = kw.Substring(1);
            DataRow r = SearchField.Select("ID='{0}'".Fmt(field)).FirstOrDefault();
            type = r["Type"] == null ? string.Empty : r["Type"].ToString();
            switch (type.ToLower())
            {
                case "date": // 2013-01-24
                    field = string.Format("CONVERT(VARCHAR(10),{0},23)", field);
                    isAccurately = true;
                    break;
                case "time": // 09:02:42
                    field = string.Format("CONVERT(VARCHAR(10),{0},108)", field);
                    isAccurately = true;
                    break;
                case "datetime": // 2013-01-24 09:02:02
                    field = string.Format("CONVERT(VARCHAR(10),{0},120)", field);
                    isAccurately = true;
                    break;
                case "group":
                    isAccurately = true;
                    break;
            }
            sb.Append(field);
            string opertator = isAccurately ? "=" : "like", vfmt = kw.ContainsWords("%", "?", "*") || isAccurately ? "'{0}'" : "'%{0}%'";

            if ((type == "group" && kw.StartsWith("(")) || kw.StartsWith("^in:")) { opertator = "in"; vfmt = "{0}"; }
            sb.AppendFormat(" {0} ", opertator);
            sb.AppendFormat(string.Format(vfmt, kw));
            if (IsDebug) MessageBox.Show(sb.ToString());
            SearchHandler(sb.ToString());
        }
        private void HideAllControls()
        {
            tbKeyword.Visible = true;
            dtp.Visible = false;
            cbb.Visible = false;
        }

        private void cbbKeyField_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (SearchField.Columns.Count < 3) return;
            HideAllControls();
            tbKeyword.Visible = false;

            string kw = tbKeyword.Text.Trim(), field = cbbKeyField.GetSelectedValue(), type;
            bool isAccurately = kw.StartsWith("=");
            if (isAccurately) kw = kw.Substring(1);
            DataRow r = SearchField.Select("ID='{0}'".Fmt(field)).FirstOrDefault();
            type = r["Type"] == null ? string.Empty : r["Type"].ToString();

            switch (type)
            {
                case "date":
                    dtp.Size = tbKeyword.Size;
                    dtp.Location = tbKeyword.Location;
                    dtp.Visible = true;
                    return;
                case "group":
                    cbb.DataSource = r["DataSource"].ToString().ToDataTable();
                    cbb.DisplayMember = "col1";
                    cbb.ValueMember = "col0";
                    cbb.Size = tbKeyword.Size;
                    cbb.Location = tbKeyword.Location;
                    cbb.Visible = true;
                    return;
                case "bool":
                    cbb.DataSource = "1=是&0=否".ToDataTable();
                    cbb.DisplayMember = "col1";
                    cbb.ValueMember = "col0";
                    cbb.Size = tbKeyword.Size;
                    cbb.Location = tbKeyword.Location;
                    cbb.Visible = true;
                    /*
                    chk.Size = tbKeyword.Size;
                    chk.Location = new Point(tbKeyword.Location.X + 5, tbKeyword.Location.Y);
                    chk.Visible = true;
                     */
                    return;
                default:
                    tbKeyword.Visible = true;
                    break;
            }
        }

        private void lblRe_Click(object sender, EventArgs e)
        {
            HideAllControls();
        }

        private void 以关键词开始ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string s = tbKeyword.Text.Trim();
            if (s.Length == 0) return;
            if (!s.EndsWith("%")) tbKeyword.Text = string.Format("{0}%", s);
        }

        private void 以关键词结尾ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string s = tbKeyword.Text.Trim();
            if (s.Length == 0) return;
            if (!s.StartsWith("%")) tbKeyword.Text = string.Format("%{0}", s);
        }

        private void 复制ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tbKeyword.Copy();
        }

        private void 清空ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tbKeyword.Text = string.Empty;
        }

        private void 粘帖ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tbKeyword.Paste();
        }
    }
}
